using System;
using Microsoft.EntityFrameworkCore;
using SovaDataService.SoModels;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

namespace SovaDataService.SoDataServices
{
    /**
     * Class dealing with the Data Service layer functionality.
     */
    public class QuestionDataService
    {
        /**
         * Retrieves all questions from the database.
         */
        public IEnumerable<Question> GetAll()
        {
            using (var db = new DbContext())
            {
                IQueryable<Question> questions = db.Questions
                    .Include(q => q.Author)
                    .Include(q => q.AcceptedAnswer)
                    .OrderBy(q => q.Id);
                return questions.ToList();
            }
        }
        /**
         * Get all questions from input ids
         */
        
        public IEnumerable<Question> GetAll(int[] questionIds)
        {
            using (var db = new DbContext())
            {
                IQueryable<Question> questions = db.Questions
                    .Include(q => q.Author)
                    .Include(q => q.AcceptedAnswer)
                    .Where(q => questionIds.Contains(q.Id));
                return questions.ToList();
            }
        }
        
        /**
         * Get all questions from search input
         */
        public IEnumerable<Question> GetQuestionsBySearch(String searchText, int accountId, out int count)
        {
            using (var db = new DbContext())
            {
                var questions = new List<Question>();
                foreach (var result in db.Questions.FromSql($"select * from search({searchText}, {accountId})").Include(q => q.Author))
                {
                    questions.Add(new Question()
                    {
                        Id = result.Id,
                        Title = result.Title,
                        Body = result.Body,
                        Score = result.Score,
                        CreationDate = result.CreationDate,
                        ClosedDate = result.ClosedDate,
                        AcceptedAnswerId = result.AcceptedAnswerId,
                        AuthorId = result.AuthorId,
                        Author = result.Author
                    });
                    Console.WriteLine($"Result(ADO): {result.Id}, {result.Title}");
                }

                count = questions.Count();
                return questions;
            }
        }

        /**
         * Retrieves a question by given id from the database.
         */
        public Question GetOne(int id)
        {
            using (var db = new DbContext())
            {
                IQueryable<Question> question = db.Questions
                    .Where(q => q.Id == id)
                    .Include(q => q.Author)
                    .Include(q => q.AcceptedAnswer)
                        .ThenInclude(a => a.Author)
                        .ThenInclude(a => a.Comments)
                    .Include(q => q.Answers)
                        .ThenInclude(a => a.Comments)
                    .Include(q => q.Comments)
                        .ThenInclude(c => c.Author);
                return question.SingleOrDefault();
            }
        }

        /**
         * Retrieves the total count without having to fetch all the questions from db.
         */
        public int GetCount()
        {
            using (var db = new DbContext())
            {
                return db.Questions.Count();
            }
        }
    }
}